home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / src / varstring.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-25  |  15.5 KB  |  696 lines

  1. /* cfengine for GNU
  2.  
  3.         Copyright (C) 1995
  4.         Free Software Foundation, Inc.
  5.  
  6.    This file is part of GNU cfengine - written and maintained 
  7.    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
  8.    Dept. of Theoretical physics, University of Oslo
  9.  
  10.    This program is free software; you can redistribute it and/or modify it
  11.    under the terms of the GNU General Public License as published by the
  12.    Free Software Foundation; either version 2, or (at your option) any
  13.    later version.
  14.  
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.   You should have received a copy of the GNU General Public License
  21.   along with this program; if not, write to the Free Software
  22.   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  23.  
  24. */
  25.  
  26.  
  27. #include "cf.defs.h"
  28. #include "cf.extern.h"
  29.  
  30. /*********************************************************************/
  31. /* Varstring: variable names                                         */
  32. /*********************************************************************/
  33.  
  34. char *VVNAMES[] =
  35.    {
  36.    "faculty",
  37.    "site",
  38.    "host",
  39.    "fqhost",
  40.    "ipaddress",
  41.    "binserver",
  42.    "sysadm",
  43.    "domain",
  44.    "timezone",
  45.    "netmask",
  46.    "nfstype",
  47.    "sensiblesize",
  48.    "sensiblecount",
  49.    "editfilesize",
  50.    "actionsequence",
  51.    "mountpattern",
  52.    "homepattern",
  53.    "addclasses",
  54.    "addinstallable",
  55.    "access",
  56.    "class",
  57.    "arch",
  58.    "date",
  59.    "year",
  60.    "allclasses",
  61.    "excludecopy",
  62.    "excludelink",
  63.    "copylinks",
  64.    "linkcopies",
  65.    "repository",
  66.    "spc",
  67.    "tab",
  68.    "lf",
  69.    "cr",
  70.    "n",
  71.    "dblquote",
  72.    "quote",
  73.    "dollar",
  74.    "repchar",
  75.    "split",
  76.    "underscoreclasses",
  77.    "interfacename",
  78.    "expireafter",
  79.    "ifelapsed",
  80.    "fileextensions",
  81.    "suspiciousnames",
  82.    "defaultcopytype",
  83.    NULL
  84.    };
  85.  
  86. /*********************************************************************/
  87. /* TOOLKIT : Varstring expansion                                     */
  88. /*********************************************************************/
  89.  
  90. TrueVar(var)
  91.  
  92. char *var;
  93.  
  94. { char buff[bufsize];
  95.   char varbuf[maxvarsize]; 
  96.  
  97. if (GetMacroValue(var))
  98.    {
  99.    bzero(buff,bufsize);
  100.    sprintf(varbuf,"$(%s)",var);
  101.    ExpandVarstring(varbuf,buff,NULL);
  102.  
  103.    if (strcmp(ToLowerStr(buff),"on") == 0)
  104.       {
  105.       return true;
  106.       }
  107.    
  108.    if (strcmp(ToLowerStr(buff),"true") == 0)
  109.       {
  110.       return true;
  111.       }
  112.    }
  113.  
  114. return false;
  115. }
  116.  
  117. /*********************************************************************/
  118.  
  119. IsVarString(str)
  120.  
  121. char *str;
  122.  
  123. { char *sp;
  124.   char left = 'x', right = 'x';
  125.   int dollar = false;
  126.   int bracks = 0, vars = 0;
  127.  
  128. for (sp = str; *sp != '\0' ; sp++)       /* check for varitems */
  129.    {
  130.    switch (*sp)
  131.       {
  132.       case '$': dollar = true;
  133.                 break;
  134.       case '(':
  135.       case '{': 
  136.                 if (dollar)
  137.             {
  138.             left = *sp;    
  139.             bracks++;
  140.             }
  141.                 break;
  142.       case ')':
  143.       case '}': 
  144.                 if (dollar)
  145.             {
  146.             bracks--;
  147.             right = *sp;
  148.             }
  149.                 break;
  150.       }
  151.  
  152.    if (left == '(' && right == ')' && dollar)
  153.       {
  154.       vars++;
  155.       dollar=false;
  156.       }
  157.  
  158.    if (left == '{' && right == '}' && dollar)
  159.       {
  160.       vars++;
  161.       dollar = false;
  162.       }
  163.    }
  164.  
  165.  
  166. if (bracks != 0)
  167.    {
  168.    yyerror("Incomplete variable syntax or bracket mismatch");
  169.    return false;
  170.    }
  171.  
  172. return vars;
  173. }
  174.  
  175. /*********************************************************************/
  176.  
  177. ExpandVarstring(string,buffer,bserver) 
  178.  
  179. char *string, *buffer, *bserver;
  180.  
  181. { char *sp,*env;
  182.   char varstring = false;
  183.   char currentitem[bufsize], scanstr[6];
  184.   int len;
  185.   time_t tloc;
  186.   
  187. if (string == 0 || strlen(string) == 0)
  188.    {
  189.    return false;
  190.    }
  191.   
  192. buffer[0] = '\0';
  193.  
  194. for (sp = string; /* No exit */ ; sp++)       /* check for varitems */
  195.    {
  196.    currentitem[0] = '\0';
  197.  
  198.    sscanf(sp,"%[^$]",currentitem);
  199.  
  200.    if (BufferOverflow(buffer,currentitem))
  201.       {
  202.       FatalError("Can't expand varstring");
  203.       }
  204.    
  205.    strcat(buffer,currentitem);
  206.    sp += strlen(currentitem);
  207.  
  208.    if (*sp == '$')
  209.       {
  210.       switch (*(sp+1))
  211.          {
  212.          case '(': 
  213.                    varstring = ')';
  214.                    break;
  215.          case '{': 
  216.                    varstring = '}';
  217.                    break;
  218.          default: 
  219.                    strcat(buffer,"$");
  220.                    continue;
  221.          }
  222.       sp++;
  223.       }
  224.  
  225.    currentitem[0] = '\0';
  226.  
  227.    if (*sp == '\0')
  228.       {
  229.       break;
  230.       }
  231.    else
  232.       {
  233.       sprintf(scanstr,"%%[^%c]",varstring);   /* select the correct terminator */
  234.       sscanf(++sp,scanstr,currentitem);               /* reduce item */
  235.  
  236.       switch (ScanVariable(currentitem))
  237.          {
  238.          case cffaculty:
  239.          case cfsite:
  240.                    if (VFACULTY[0] == '\0')
  241.                       {
  242.                       yyerror("faculty/site undefined variable");
  243.                       }
  244.  
  245.            if (BufferOverflow(buffer,VFACULTY))
  246.               {
  247.               FatalError("Can't expand varstring");
  248.               }
  249.                    strcat(buffer,VFACULTY);
  250.                    break;
  251.  
  252.  
  253.          case cfhost:
  254.                 if (strlen(VUQNAME) == 0)
  255.                {
  256.                if (BufferOverflow(buffer,VDEFAULTBINSERVER.name))
  257.               {
  258.               FatalError("Can't expand varstring");
  259.               }
  260.                strcat(buffer,VDEFAULTBINSERVER.name);
  261.                }
  262.             else
  263.                {
  264.                if (BufferOverflow(buffer,VUQNAME))
  265.               {
  266.               FatalError("Can't expand varstring");
  267.               }
  268.                strcat(buffer,VUQNAME);
  269.                }
  270.                     break;
  271.  
  272.      case cffqhost:
  273.                  if (BufferOverflow(buffer,VFQNAME))
  274.               {
  275.               FatalError("Can't expand varstring");
  276.               }
  277.                     strcat(buffer,VFQNAME);
  278.                     break;
  279.  
  280.      case cfipaddr:
  281.                if (BufferOverflow(buffer,VIPADDRESS))
  282.               {
  283.               FatalError("Can't expand varstring");
  284.               }
  285.            strcat(buffer,VIPADDRESS);
  286.            break;
  287.            
  288.          case cfbinserver:
  289.                     if (ACTION != links && ACTION != required)
  290.                        {
  291.                        yyerror("Inappropriate use of variable binserver");
  292.                        FatalError("Bad variable");
  293.                        }
  294.  
  295.             if (BufferOverflow(buffer,"$(binserver)"))
  296.               {
  297.               FatalError("Can't expand varstring");
  298.               }
  299.                     strcat(buffer,"$(binserver)");
  300.                     break;
  301.  
  302.          case cfsysadm:
  303.                    if (VSYSADM[0] == '\0')
  304.                       {
  305.                       yyerror("sysadm undefined variable");
  306.                       }
  307.  
  308.            if (BufferOverflow(buffer,VSYSADM))
  309.               {
  310.               FatalError("Can't expand varstring");
  311.               }
  312.                    strcat(buffer,VSYSADM);
  313.                    break;
  314.  
  315.          case cfdomain:
  316.                    if (VDOMAIN[0] == '\0')
  317.                       {
  318.                       yyerror("domain undefined variable");
  319.                       }
  320.  
  321.            if (BufferOverflow(buffer,VDOMAIN))
  322.               {
  323.               FatalError("Can't expandvarstring");
  324.               }
  325.                    strcat(buffer,ToLowerStr(VDOMAIN));
  326.                    break;
  327.  
  328.          case cfnfstype:
  329.                if (BufferOverflow(buffer,VNFSTYPE))
  330.               {
  331.               FatalError("Can't expandvarstring");
  332.               }
  333.                    strcat(buffer,VNFSTYPE);
  334.                    break;
  335.  
  336.          case cftimezone:
  337.                    if (VTIMEZONE == NULL)
  338.                       {
  339.                       yyerror("timezone undefined variable");
  340.                       }
  341.  
  342.            if (BufferOverflow(buffer,VTIMEZONE->name))
  343.               {
  344.               FatalError("Can't expandvarstring");
  345.               }
  346.                    strcat(buffer,VTIMEZONE->name);
  347.                    break;
  348.  
  349.          case cfclass:
  350.                if (BufferOverflow(buffer,CLASSTEXT[VSYSTEMHARDCLASS]))
  351.               {
  352.               FatalError("Can't expandvarstring");
  353.               }
  354.                    strcat(buffer,CLASSTEXT[VSYSTEMHARDCLASS]);
  355.                    break;
  356.  
  357.          case cfarch:
  358.                if (BufferOverflow(buffer,VARCH))
  359.               {
  360.               FatalError("Can't expandvarstring");
  361.               }
  362.                    strcat(buffer,VARCH);
  363.                    break;
  364.  
  365.      case cfdate:
  366.          
  367.                if ((tloc = time((time_t *)NULL)) == -1)
  368.               {
  369.               sprintf(OUTPUT,"Couldn't read system clock\n");
  370.               CfLog(cferror,"Couldn't read clock","time");
  371.               }
  372.  
  373.                if (BufferOverflow(buffer,ctime(&tloc)))
  374.               {
  375.               FatalError("Can't expandvarstring");
  376.               }
  377.            else
  378.               {
  379.               strcpy(buffer,ctime(&tloc));
  380.               buffer[strlen(buffer)-1] = '\0';
  381.               }
  382.                break;
  383.            
  384.      case cfyear:
  385.                if (BufferOverflow(buffer,VYEAR))
  386.               {
  387.               FatalError("Can't expandvarstring");
  388.               }
  389.            else
  390.               {
  391.               strcat(buffer,VYEAR);
  392.               }
  393.                break;
  394.  
  395.      case cfallclass:
  396.                if (BufferOverflow(buffer,ALLCLASSBUFFER))
  397.               {
  398.               FatalError("Can't expandvarstring");
  399.               }
  400.                    strcat(buffer,ALLCLASSBUFFER);
  401.                    break;
  402.  
  403.      case cfspc:
  404.                 if (BufferOverflow(buffer," "))
  405.               {
  406.               FatalError("Can't expandvarstring");
  407.               }
  408.                strcat(buffer," ");
  409.            break;
  410.  
  411.      case cftab:
  412.                 if (BufferOverflow(buffer," "))
  413.               {
  414.               FatalError("Can't expandvarstring");
  415.               }
  416.                strcat(buffer,"\t");
  417.            break;
  418.  
  419.      case cflf:
  420.                 if (BufferOverflow(buffer," "))
  421.               {
  422.               FatalError("Can't expandvarstring");
  423.               }
  424.                strcat(buffer,"\012");
  425.            break;
  426.            
  427.          case cfcr:
  428.                 if (BufferOverflow(buffer," "))
  429.               { 
  430.               FatalError("Can't expandvarstring");
  431.               }
  432.                strcat(buffer,"\015");
  433.            break;
  434.  
  435.          case cfn:
  436.                 if (BufferOverflow(buffer," "))
  437.               { 
  438.               FatalError("Can't expandvarstring");
  439.               }
  440.                strcat(buffer,"\n");
  441.            break;
  442.  
  443.      case cfdblquote:
  444.                 if (BufferOverflow(buffer," "))
  445.               { 
  446.               FatalError("Can't expandvarstring");
  447.               }
  448.                strcat(buffer,"\"");
  449.            break;
  450.          case cfquote:
  451.                 if (BufferOverflow(buffer," "))
  452.               { 
  453.               FatalError("Can't expandvarstring");
  454.               }
  455.                strcat(buffer,"\'");
  456.            break;
  457.          case cfdollar:
  458.                 if (BufferOverflow(buffer," "))
  459.               { 
  460.               FatalError("Can't expandvarstring");
  461.               }
  462.                strcat(buffer,"$");
  463.            break;
  464.            
  465.  
  466.      case cfrepchar:
  467.                 if (BufferOverflow(buffer," "))
  468.               {
  469.               FatalError("Can't expandvarstring");
  470.               }
  471.            len = strlen(buffer);
  472.                buffer[len] = REPOSCHAR;
  473.            buffer[len+1] = '\0';
  474.                break;
  475.  
  476.      case cflistsep:
  477.                 if (BufferOverflow(buffer,""))
  478.               {
  479.               FatalError("Can't expandvarstring");
  480.               }
  481.            len = strlen(buffer);
  482.                buffer[len] = LISTSEPARATOR;
  483.            buffer[len+1] = '\0';
  484.                    break;
  485.  
  486.          default:  
  487.                    if ((env = GetMacroValue(currentitem)) != NULL)
  488.                       {
  489.                if (BufferOverflow(buffer,env))
  490.                     {
  491.                  FatalError("Can't expandvarstring");
  492.                  }
  493.                       strcat(buffer,env);
  494.                       break;
  495.                       }
  496.  
  497.                    printf("Bad variable $(%s)\n",currentitem);
  498.                    FatalError("No such variable or out of context");
  499.          }
  500.  
  501.       sp += strlen(currentitem);
  502.       currentitem[0] = '\0';
  503.       }
  504.    }
  505.  
  506. return varstring;
  507. }
  508.  
  509. /*********************************************************************/
  510.  
  511. ExpandVarbinserv(string,buffer,bserver) 
  512.  
  513. char *string, *buffer, *bserver;
  514.  
  515. { char *sp,*env;
  516.   char varstring = false;
  517.   char currentitem[bufsize], scanstr[6];
  518.   int len;
  519.  
  520. Debug("ExpandVarbinserv %s, ",string);
  521.  
  522. if (bserver != NULL)
  523.    {
  524.    Debug("(Binserver is %s)\n",bserver);
  525.    }
  526.  
  527. buffer[0] = '\0';
  528.  
  529. for (sp = string; /* No exit */ ; sp++)       /* check for varitems */
  530.    {
  531.    currentitem[0] = '\0';
  532.  
  533.    sscanf(sp,"%[^$]",currentitem);
  534.  
  535.    strcat(buffer,currentitem);
  536.    sp += strlen(currentitem);
  537.  
  538.    if (*sp == '$')
  539.       {
  540.       switch (*(sp+1))
  541.          {
  542.          case '(': 
  543.                    varstring = ')';
  544.                    break;
  545.          case '{': 
  546.                    varstring = '}';
  547.                    break;
  548.          default: 
  549.                    strcat(buffer,"$");
  550.                    continue;
  551.          }
  552.       sp++;
  553.       }
  554.  
  555.    currentitem[0] = '\0';
  556.  
  557.    if (*sp == '\0')
  558.       {
  559.       break;
  560.       }
  561.    else
  562.       {
  563.       sprintf(scanstr,"%%[^%c]",varstring);   /* select the correct terminator */
  564.       sscanf(++sp,scanstr,currentitem);               /* reduce item */
  565.  
  566.       switch (ScanVariable(currentitem))
  567.          {
  568.          case cfbinserver:
  569.             if (BufferOverflow(buffer,bserver))
  570.               {
  571.               FatalError("Can't expand varstring");
  572.               }
  573.                     strcat(buffer,bserver);
  574.                     break;
  575.          }
  576.  
  577.       sp += strlen(currentitem);
  578.       currentitem[0] = '\0';
  579.       }
  580.    }
  581.  
  582. return varstring;
  583. }
  584.  
  585. /*********************************************************************/
  586.  
  587. enum vnames ScanVariable(name)
  588.  
  589. char *name;
  590.  
  591. { int i = nonexistentvar;
  592.  
  593. for (i = 0; VVNAMES[i] != '\0'; i++)
  594.    {
  595.    if (strcmp(VVNAMES[i],ToLowerStr(name)) == 0)
  596.       {
  597.       return (enum vnames) i;
  598.       }
  599.    }
  600.  
  601. return (enum vnames) i;
  602. }
  603.  
  604.  
  605. /*********************************************************************/
  606.  
  607. struct Item *SplitVarstring(varstring,sep)
  608.  
  609.  /* Splits a string containing a separator like : 
  610.     into a linked list of separate items, */
  611.  
  612. char *varstring;
  613. char sep;
  614.  
  615. { struct Item *liststart = NULL;
  616.   char format[6], *sp;
  617.   char node[maxlinksize];
  618.   char buffer[bufsize], variable[maxvarsize];
  619.   char before[bufsize],after[bufsize],result[bufsize];
  620.   int i;
  621.   
  622. Debug("SplitVarstring(%s,%c=%d)\n",varstring,sep,sep);
  623.  
  624. bzero(before,bufsize);
  625. bzero(after,bufsize);
  626.  
  627. if (strcmp(varstring,"") == 0)   /* Handle path = / as special case */
  628.    {
  629.    AppendItem(&liststart,"/",NULL);
  630.    return liststart;
  631.    }
  632.  
  633. if (!IsVarString(varstring))
  634.    {
  635.    AppendItem(&liststart,varstring,NULL);
  636.    return liststart;   
  637.    }
  638.  
  639. sprintf(format,"%%[^%c]",sep);   /* set format string to search */
  640.  
  641. i = 0; /* extract variable */
  642.  
  643. for(sp = varstring; *sp != '$' && *sp != '\0' ; sp++)
  644.    {
  645.    before[i++] = *sp;
  646.    }
  647. before[i] = '\0';
  648. i = 0;
  649.  
  650. while (*sp != ')' && *sp != '}' && *sp != '\0')
  651.    {
  652.    variable[i++] = *sp++;
  653.    }
  654. variable[i] = *sp++;
  655. variable[i+1] = '\0';
  656. i = 0;
  657.  
  658. ExpandVarstring(variable,buffer,"");
  659.  
  660. while(*sp != '\0')
  661.    {
  662.    after[i++] = *sp++;
  663.    }
  664.  
  665. for (sp = buffer; *sp != '\0'; sp++)
  666.    {
  667.    bzero(node,maxlinksize);
  668.    sscanf(sp,format,node);
  669.  
  670.    if (strlen(node) == 0)
  671.       {
  672.       continue;
  673.       }
  674.    
  675.    sp += strlen(node)-1;
  676.  
  677.    if (strlen(before)+strlen(node)+strlen(after) >= bufsize)
  678.       {
  679.       FatalError("Buffer overflow expanding variable string");
  680.       printf("Concerns: %s%s%s in %s",before,node,after,varstring);
  681.       }
  682.    
  683.    sprintf(result,"%s%s%s",before,node,after);
  684.  
  685.    AppendItem(&liststart,result,NULL);
  686.  
  687.    if (*sp == '\0')
  688.       {
  689.       break;
  690.       }
  691.    }
  692.  
  693. return liststart;
  694. }
  695.  
  696.